package com.sinosun.autotestmachine.tools.proxy.callback;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;

import com.sinosun.autotestmachine.tools.Collector.BaseCollector;
import com.sinosun.autotestmachine.tools.Collector.Cache;
import com.sinosun.autotestmachine.tools.Collector.FileCancelCollector;
import com.sinosun.autotestmachine.tools.Collector.FileloadCollector;
import com.sinosun.autotestmachine.tools.Collector.MsgListenerCollector;
import com.sinosun.autotestmachine.tools.Collector.MsgSendCollector;
import com.sinosun.autotestmachine.tools.Collector.NotiSendCollector;
import com.sinosun.autotestmachine.tools.proxy.ErrorCode;
import com.sinosun.autotestmachine.tools.proxy.callback.buddy.BudduyActionType;
import com.sinosun.autotestmachine.tools.proxy.callback.buddy.BuddyActionInformation;
import com.sinosun.autotestmachine.tools.proxy.callback.buddy.BuddyMsg;
import com.sinosun.mstplib.ConnectionListener;
import com.sinosun.mstplib.DeviceStatus;
import com.sinosun.mstplib.DeviceType;
import com.sinosun.mstplib.FileCallback;
import com.sinosun.mstplib.MessageListener;
import com.sinosun.mstplib.MessageSendCallback;
import com.sinosun.mstplib.MstpClient;
import com.sinosun.mstplib.NotificationListener;
import com.sinosun.mstplib.NotificationSendCallback;
import com.sinosun.mstplib.PresentStatus;
import com.sinosun.mstplib.buddy.AddPolicy;
import com.sinosun.mstplib.buddy.BuddyListener;
import com.sinosun.mstplib.clouddisk.CloudDiskCallback;
import com.sinosun.mstplib.message.AudioMessageBody;
import com.sinosun.mstplib.message.FileMessageBody;
import com.sinosun.mstplib.message.ImageMessageBody;
import com.sinosun.mstplib.message.Message;
import com.sinosun.mstplib.message.MessageStatus;
import com.sinosun.mstplib.message.MessageType;
import com.sinosun.mstplib.message.TextMessageBody;
import com.sinosun.mstplib.message.VideoMessageBody;
import com.sinosun.mstplib.topic.TopicListener;

import android.util.Log;

public class CallbackWrapper {
	
	private static Map<String, SCInfo> scinfoMap = new ConcurrentHashMap<String, SCInfo>();		//发送消息的缓存
	private static Map<String, NSCInfo> nscinfoMap = new ConcurrentHashMap<String, NSCInfo>();
	private static Map<String, FCInfo> fileMap = new ConcurrentHashMap<String, FCInfo>();
	private static Set<NotificationInfo> notiRecv = new ConcurrentSkipListSet<NotificationInfo>();
	private static Map<String, CoreInfo> msgMap = new ConcurrentHashMap<String, CoreInfo>();
	private static Map<String, MsgCodeInfo> msgCodeMap = new ConcurrentHashMap<String, MsgCodeInfo>();
	private static ProxyMessageSendCallback pmsc;
	private static ProxyMessageListener pml;
	private volatile static ProxyMessageListener pml0;
	private volatile static ProxyMessageListener pml1;
	private volatile static ProxyMessageListener pml2;
	private volatile static ProxyFileCallback pfc;
	private volatile static ProxyCloudDiskCallback pcdc;
	private volatile static ProxyNotificationSendCallback pnsc;
	private volatile static ProxyNotificationListener pnl;
	private volatile static ProxyTopicListener ptl;
	private volatile static ProxyBuddyListener pbl;
	
	public static void makeConnectionListener(final MstpClient client, final BaseCollector collector) {
    	client.setConnectionListener(new ConnectionListener() {
			@Override public void onConnected() {
				Log.e("XXX", "onConnected");
				collector.setResult(ErrorCode.SUCCESS);
				collector.countDown();
			}
			@Override public void onDisconnected(int arg0) {
				Log.e("XXX", "onDisconnected arg0 = " + arg0);
				collector.setResult(arg0);
				collector.countDown();
			}
			
			@Override public void onConnectionLost() { }
			@Override public void onOtherDeviceStatusChanged(DeviceType arg0, DeviceStatus arg1, PresentStatus arg2) {
				
			}
    	});
    	
    	notiRecv.clear();
    	client.setNotificationListener(new NotificationListener() {
			@Override public void onNotificationRecv(String arg0, String arg1, String arg2) {
				NotificationInfo ele = new NotificationInfo();
				ele.setNotiContent(arg0);
				ele.setFrom(arg1);
				notiRecv.add(ele);
				if (pnl != null) {
					pnl.onNotificationRecv(arg0, arg1, arg2);
				}
			}
    	});
    	
    	nscinfoMap.clear();
    	client.setNotificationSendCallback(new NotificationSendCallback() {
			@Override public void onNotificationFail(String arg0, int arg1) {
				NSCInfo ele = new NSCInfo();
				ele.setFlag(false);
				ele.setReason(arg1);
				nscinfoMap.put(arg0, ele);
				if (pnsc != null) {
					pnsc.onNotificationFail(arg0, arg1);
				}
			}

			@Override public void onNotificationSuccuss(String arg0) {
				NSCInfo ele = new NSCInfo();
				ele.setFlag(true);
				nscinfoMap.put(arg0, ele);
				if (pnsc != null) {
					pnsc.onNotificationSuccuss(arg0);
				}
			}
    	});
    	
    	scinfoMap.clear();
    	client.setMessageCallback(new MessageSendCallback() {
			@Override public void onFail(String arg0, int arg1) {
				scinfoMap.put(arg0, new SCInfo(false, arg1));
				if (pmsc != null) {
					pmsc.onFail(arg0, arg1);
				}
			}

			@Override public void onProgress(String arg0, int arg1) {
				if (pmsc != null) {
					pmsc.onProgress(arg0, arg1);
				}
			}

			@Override public void onSuccess(String arg0, Message arg1) {
				scinfoMap.put(arg0, new SCInfo(true, arg1));
				if (pmsc != null) {
					pmsc.onSuccess(arg0, arg1);
				}
			}
    	});
    	
    	msgMap.clear();
    	msgCodeMap.clear();
    	client.setMessageListener(new MessageListener() {
			@Override public boolean onMessageRecv(List<Message> arg0) {
				for (Message ele : arg0) {
					msgMap.put(ele.getMsgId(), new CoreInfo(ele));
					Log.e("XXX", "recv msgId -> " + ele.getMsgId());
				}
				
				if (pml != null) {
					pml.onMessageRecv(arg0);
				}
				
				if (pml0 != null) {
					pml0.onMessageRecv(arg0);
				}
				
				return true;
			}

			@Override public void onMessageStatus(String arg0, MessageStatus arg1, String arg2, List<String> arg3, String arg4) {
				MsgCodeInfo ele = new MsgCodeInfo();
				ele.setMessageStatus(arg1);
				msgCodeMap.put(arg0, ele);
				if (pml1 != null) {
					pml1.onMessageStatus(arg0, arg1, arg2, arg3, arg4);
				}
				
				if (pml2 != null) {
					pml2.onMessageStatus(arg0, arg1, arg2, arg3, arg4);
				}
			}
    	});
    	
    	client.setFileCallback(new FileCallback() {
			@Override public void onDownloadFail(String arg0, int arg1) {
				FCInfo ele = new FCInfo();
				ele.setUploadFlag(false);
				ele.setFlag(false);
				ele.setReason(arg1);
				fileMap.put(arg0, ele);
				
				if (pfc != null) {
					pfc.onDownloadFail(arg0, arg1);
				}
			}
			
			@Override public void onDownloadProgress(String arg0, int arg1) {
				Log.e("XXX", "onDownloadProgress arg0 " + arg0 + ", arg1 " + arg1);
				if (pfc != null) {
					pfc.onDownloadProgress(arg0, arg1);
				}
			}
			
			@Override public void onDownloadSuccess(String arg0) {
				FCInfo ele = new FCInfo();
				ele.setUploadFlag(false);
				ele.setFlag(true);
				fileMap.put(arg0, ele);
				if (pfc != null) {
					pfc.onDownloadSuccess(arg0);
				}
			}

			@Override public void onUploadFail(String arg0, int arg1) {
				FCInfo ele = new FCInfo();
				ele.setUploadFlag(true);
				ele.setFlag(false);
				ele.setReason(arg1);
				fileMap.put(arg0, ele);
				if (pfc != null) {
					pfc.onUploadFail(arg0, arg1);
				}
			}

			@Override public void onUploadProgress(String arg0, int arg1) {
				Log.e("XXX", "onUploadProgress arg0 " + arg0 + ", arg1 " + arg1);
				if (pfc != null) {
					pfc.onUploadProgress(arg0, arg1);
				}
			}

			@Override public void onUploadSuccess(String arg0, String arg1) {
				FCInfo ele = new FCInfo();
				ele.setUploadFlag(true);
				ele.setFlag(true);
				ele.setFileId(arg1);
				fileMap.put(arg0, ele);
				if (pfc != null) {
					pfc.onUploadSuccess(arg0, arg1);
				}
			}

			@Override
			public void onDownloadPause(String arg0, int arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onDownloadResume(String arg0, int arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUploadPause(String arg0, int arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUploadResume(String arg0, int arg1) {
				// TODO Auto-generated method stub
				
			}
		});
    	
    	client.getCloudDiskManager().setCallback(new CloudDiskCallback() {
			@Override public void onDownloadFail(String arg0, int arg1) {
				FCInfo ele = new FCInfo();
				ele.setUploadFlag(false);
				ele.setFlag(false);
				ele.setReason(arg1);
				fileMap.put(arg0, ele);
				if (pcdc != null) {
					pcdc.onDownloadFail(arg0, arg1);
				}
			}

			@Override public void onDownloadProgress(String arg0, int arg1) {
				if (pcdc != null) {
					pcdc.onDownloadProgress(arg0, arg1);
				}
			}

			@Override public void onDownloadSuccess(String arg0) {
				FCInfo ele = new FCInfo();
				ele.setUploadFlag(false);
				ele.setFlag(true);
				fileMap.put(arg0, ele);
				if (pcdc != null) {
					pcdc.onDownloadSuccess(arg0);
				}
			}

			@Override public void onUploadFail(String arg0, int arg1) {
				FCInfo ele = new FCInfo();
				ele.setUploadFlag(true);
				ele.setFlag(false);
				ele.setReason(arg1);
				fileMap.put(arg0, ele);
				if (pcdc != null) {
					pcdc.onUploadFail(arg0, arg1);
				}
			}

			@Override public void onUploadProgress(String arg0, int arg1) {
				if (pcdc != null) {
					pcdc.onUploadProgress(arg0, arg1);
				}
			}

			@Override public void onUploadSuccess(String arg0, String arg1) {
				FCInfo ele = new FCInfo();
				ele.setUploadFlag(true);
				ele.setFlag(true);
				ele.setFileId(arg1);
				fileMap.put(arg0, ele);
				if (pfc != null) {
					pfc.onUploadSuccess(arg0, arg1);
				}
				if (pcdc != null) {
					pcdc.onUploadSuccess(arg0, arg1);
				}
			}

			@Override
			public void onDownloadPause(String arg0, int arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onDownloadResume(String arg0, int arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUploadPause(String arg0, int arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUploadResume(String arg0, int arg1) {
				// TODO Auto-generated method stub
				
			}
    	});
    	
    	client.getTopicManager().setTopicListener(new TopicListener() {
			@Override public void onAddedToTopic(String arg0, String arg1, String arg2) {
				Log.e("MMM", "onAddedToTopic topicId=" + arg0 + ", tmp=" + arg1 + ", extraInfo=" + arg2);
				if (ptl != null) {
					ptl.onAddedToTopic(arg0, arg1, arg2);
				}
			}

			@Override public void onKickOutNotify(String arg0, String arg1, String arg2) {
				Log.e("MMM", "onKickOutNotity topicId=" + arg0 + ", tmp=" + arg1 + ", extraInfo=" + arg2);
				if (ptl != null) {
					ptl.onKickOutNotity(arg0, arg1, arg2);
				}
			}

			@Override public void onMemberJoin(String arg0, String arg1, String arg2) {
				Log.e("MMM", "onMemberJoin topicId=" + arg0 + ", tmp=" + arg1 + ", extraInfo=" + arg2);
				if (ptl != null) {
					ptl.onMemberJoin(arg0, arg1, arg2);
				}
			}

			@Override public void onMemberLeave(String arg0, String arg1, String arg2) {
				Log.e("MMM", "onMemberLeave topicId=" + arg0 + ", tmp=" + arg1 + ", extraInfo=" + arg2);
				if (ptl != null) {
					ptl.onMemberLeave(arg0, arg1, arg2);
				}
			}

			@Override public void onTopicInfoUpdate(String arg0, String arg1) {
				Log.e("MMM", "onTopicInfoUpdate topicId=" + arg0 + ", extraInfo=" + arg1);
				if (ptl != null) {
					ptl.onTopicInfoUpdate(arg0, arg1);
				}
			}

			@Override public void onTopicClose(String arg0, String arg1, String arg2) {
				Log.e("MMM", "onTopicClose topicId=" + arg0 + ",sponsor=" + arg1 + ",extInfo=" + arg2);
				if (ptl != null) {
					ptl.onTopicClose(arg0, arg1, arg2);
				}
			}

			@Override public void onTopicOpen(String arg0, String arg1, String arg2) {
				Log.e("MMM", "onTopicOpen topicId=" + arg0 + ",sponsor=" + arg1 + ",extInfo=" + arg2);
				if (ptl != null) {
					ptl.onTopicOpen(arg0, arg1, arg2);
				}
			}

			@Override public void onTopicTransfer(String arg0, String arg1, String arg2, String arg3) {
				Log.e("MMM", "onTopicTransfer() topicId=" + arg0 + ",sponsor=" + arg1 + ",accepter" + arg2 + ",extInfo=" + arg1);
				if (ptl != null) {
					ptl.onTopicTransfer(arg0, arg1, arg2, arg3);
				}
			}
    	});
    	
    	client.getBuddyManager().setBuddyListener(new BuddyListener() {
			@Override public void onAddBuddy(String arg0, String arg1, String arg2, String arg3) {
				Log.e("XXX", "onAddBuddy");
				BuddyActionInformation item = new BuddyActionInformation();
				item.setBudduyActionType(BudduyActionType.AddBuddy);
				BuddyMsg msg = new BuddyMsg();
				msg.setArg(1, arg0);
				msg.setArg(2, arg1);
				msg.setArg(3, arg2);
				msg.setArg(4, arg3);
				item.setBuddyMsg(msg);
				Cache.allBuddyAction.add(item);
				if (pbl != null) {
					pbl.onAddBuddy(arg0, arg1, arg2, arg3);
				}
			}

			@Override public void onAddedPolicyChanged(AddPolicy arg0, String arg1, String arg2) {
				Log.e("XXX", "onAddedPolicyChanged");
				BuddyActionInformation item = new BuddyActionInformation();
				item.setBudduyActionType(BudduyActionType.AddedPolicyChanged);
				BuddyMsg msg = new BuddyMsg();
				msg.setArg(1, arg1);
				msg.setArg(2, arg2);
				msg.setAddPolicy(arg0);
				item.setBuddyMsg(msg);
				Cache.allBuddyAction.add(item);
				if (pbl != null) {
					pbl.onAddedPolicyChanged(arg0, arg1, arg2);
				}
			}

			@Override public void onAgreeAddBuddy(String arg0, String arg1, String arg2) {
				Log.e("XXX", "onAgreeAddBuddy");
				BuddyActionInformation item = new BuddyActionInformation();
				item.setBudduyActionType(BudduyActionType.AgreeAddBuddy);
				BuddyMsg msg = new BuddyMsg();
				msg.setArg(1, arg0);
				msg.setArg(2, arg1);
				msg.setArg(3, arg2);
				item.setBuddyMsg(msg);
				Cache.allBuddyAction.add(item);
				if (pbl != null) {
					pbl.onAgreeAddBuddy(arg0, arg1, arg2);
				}
			}

			@Override public void onBuddyInfoChanged(String arg0, String arg1, String arg2) {
				Log.e("XXX", "onBuddyInfoChanged");
				BuddyActionInformation item = new BuddyActionInformation();
				item.setBudduyActionType(BudduyActionType.BuddyInfoChanged);
				BuddyMsg msg = new BuddyMsg();
				msg.setArg(1, arg0);
				msg.setArg(2, arg1);
				msg.setArg(3, arg2);
				item.setBuddyMsg(msg);
				Cache.allBuddyAction.add(item);
				if (pbl != null) {
					pbl.onBuddyInfoChanged(arg0, arg1, arg2);
				}
			}

			@Override public void onRefuseAddBuddy(String arg0, String arg1, String arg2) {
				Log.e("XXX", "onRefuseAddBuddy");
				BuddyActionInformation item = new BuddyActionInformation();
				item.setBudduyActionType(BudduyActionType.RefuseAddBuddy);
				BuddyMsg msg = new BuddyMsg();
				msg.setArg(1, arg0);
				msg.setArg(2, arg1);
				msg.setArg(3, arg2);
				item.setBuddyMsg(msg);
				Cache.allBuddyAction.add(item);
				if (pbl != null) {
					pbl.onRefuseAddBuddy(arg0, arg1, arg2);
				}
			}

			@Override public void onRemoveBuddy(String arg0) {
				Log.e("XXX", "onRemoveBuddy");
				BuddyActionInformation item = new BuddyActionInformation();
				item.setBudduyActionType(BudduyActionType.RemoveBuddy);
				BuddyMsg msg = new BuddyMsg();
				msg.setArg(1, arg0);
				item.setBuddyMsg(msg);
				Cache.allBuddyAction.add(item);
				if (pbl != null) {
					pbl.onRemoveBuddy(arg0);
				}
			}
    	});
    }
	
	public static void makeBuddyListener(final BaseCollector collector, final BuddyActionInformation tag) {
		if (Cache.allBuddyAction.contains(tag)) {
			collector.setResult(ErrorCode.SUCCESS);
			collector.countDown();
			return;
		}
		pbl = new ProxyBuddyListener() {
			@Override public void onAddBuddy(String arg0, String arg1, String arg2, String arg3) {
				Log.e("XXX", "onAddBuddy arg0=" + arg0 + ",arg1=" + arg1 + ",arg2=" + arg2 + ",arg3=" + arg3);
				if (Cache.allBuddyAction.contains(tag)) {
					collector.setResult(ErrorCode.SUCCESS);
					collector.countDown();
				}
			}

			@Override public void onAddedPolicyChanged(AddPolicy arg0, String arg1, String arg2) {
				Log.e("XXX", "onAddedPolicyChanged arg0=" + arg0 + ",arg1=" + arg1 + ",arg2=" + arg2);
				if (Cache.allBuddyAction.contains(tag)) {
					collector.setResult(ErrorCode.SUCCESS);
					collector.countDown();
				}
			}

			@Override public void onAgreeAddBuddy(String arg0, String arg1, String arg2) {
				Log.e("XXX", "onAgreeAddBuddy arg0=" + arg0 + ",arg1=" + arg1 + ",arg2=" + arg2);
				for (BuddyActionInformation ele : Cache.allBuddyAction) {
					Log.e("XXX", "ele=" + ele.toString());
				}
				if (Cache.allBuddyAction.contains(tag)) {
					collector.setResult(ErrorCode.SUCCESS);
					collector.countDown();
				}
			}

			@Override public void onBuddyInfoChanged(String arg0, String arg1, String arg2) {
				Log.e("XXX", "onBuddyInfoChanged arg0=" + arg0 + ",arg1=" + arg1 + ",arg2=" + arg2);
				if (Cache.allBuddyAction.contains(tag)) {
					collector.setResult(ErrorCode.SUCCESS);
					collector.countDown();
				}
			}

			@Override public void onRefuseAddBuddy(String arg0, String arg1, String arg2) {
				Log.e("XXX", "onRefuseAddBuddy arg0=" + arg0 + ",arg1=" + arg1 + ",arg2=" + arg2);
				if (Cache.allBuddyAction.contains(tag)) {
					collector.setResult(ErrorCode.SUCCESS);
					collector.countDown();
				}
			}

			@Override public void onRemoveBuddy(String arg0) {
				Log.e("XXX", "onRemoveBuddy arg0=" + arg0);
				if (Cache.allBuddyAction.contains(tag)) {
					collector.setResult(ErrorCode.SUCCESS);
					collector.countDown();
				}
			}
		};
	}
	
	public static void clearBuddyListener() {
		pbl = null;
	}
	
	public static void makeTopicListener() {
		
	}
	
	public static void makeNotificationListener(final NotiSendCollector collector) {
		if (detectNotification(collector)) {
			return;
		}
		pnl = new ProxyNotificationListener() {
			@Override public void onNotificationRecv(String payload, String from, String group) {
				detectNotification(collector);
			}
		};
	}
	
	private static boolean detectNotification(NotiSendCollector collector) {
		int count = 0;
		for (int i = 0; i < collector.getCache().size(); i++) {
			NotificationInfo item = collector.getCache().get(i);
			Iterator<NotificationInfo> it = notiRecv.iterator();
			while (it.hasNext()) {
				NotificationInfo tag = it.next();
				
				if (tag.getNotiContent().equals(item.getNotiContent()) && tag.getFrom().equals(item.getFrom())) {
					count++;
				}
			}
		}
		
		if (count == collector.getCache().size()) {
			collector.setResult(ErrorCode.SUCCESS);
			collector.countDown();
			return true;
		}
		
		return false;
	}
	
	public static void clearNoti() {
		notiRecv.clear();
	}
	
	public static void clearNotificationListener() {
		pnl = null;
	}
	
	public static void clearProxyNotificationSendCallback() {
		pnsc = null;
	}
	
	public static void makeProxyNotificationSendCallback(final NotiSendCollector collector) {
		if (detectNotificationSendCallback(collector)) {
			return;
		}
		pnsc = new ProxyNotificationSendCallback() {
			@Override public void onNotificationFail(String arg0, int arg1) {
				detectNotificationSendCallback(collector);
			}

			@Override public void onNotificationSuccuss(String arg0) {
				detectNotificationSendCallback(collector);
			}
		};
	}
	
	private static boolean detectNotificationSendCallback(NotiSendCollector collector) {
    	int count = 0;
    	for (String ele : collector.getNotiIds()) {		//遍历比较内存中的发送情况
    		if (nscinfoMap.containsKey(ele) && nscinfoMap.get(ele).getFlag()) {
    			count++;
    		} else if (nscinfoMap.containsKey(ele) && !nscinfoMap.get(ele).getFlag()) {
    			collector.setResult(nscinfoMap.get(ele).getReason());		//存在一个发送失败的情况，直接返回监听结果
        		collector.countDown();
    			return true;
    		}
    	}
    	
    	if (count == collector.getMessageIDs().size()) {		//所有都发送成功，认为监听成功
    		collector.setResult(0);
    		collector.countDown();
    		for (int i = 0; i < collector.getMessageIDs().size(); i++) {			//当所有发送数据都发送成功时，将数据缓存
    			Cache.allNotification.put(collector.getCache().get(i).getTagId(), collector.getCache().get(i));
    		}
    		return true;
    	} else {
    		return false;
    	}
	}
    
    public static void makeFileUploadCallbackAndCancel(MstpClient mstpClient, FileCancelCollector collector) {
    	makeFileCallbackAndCancel(mstpClient, collector, true);
    }
    
    public static void makeFileDownloadCallbackAndCancel(MstpClient mstpClient, FileCancelCollector collector) {
    	makeFileCallbackAndCancel(mstpClient, collector, false);
    }
    
    public static void makeUploadDuplicateFileListener(final FileloadCollector collector) {
    	pfc = new ProxyFileCallback() {
			@Override public void onDownloadFail(String arg0, int arg1) { }
			@Override public void onDownloadProgress(String arg0, int arg1) { }
			@Override public void onDownloadSuccess(String arg0) { }

			@Override public void onUploadFail(String arg0, int arg1) {
				if (collector.getFileInfos().get(0).getTrasactionId().equals(arg0)) {
					collector.setResult(arg1);
					collector.countDown();
				}
			}

			@Override public void onUploadProgress(String arg0, int arg1) {
				if (collector.getFileInfos().get(0).getTrasactionId().equals(arg0) && arg1 != 100) {
					collector.setResult(ErrorCode.ERR_UNEXPECT_RESULT);
					collector.countDown();
				} else if (collector.getFileInfos().get(0).getTrasactionId().equals(arg0) && arg1 == 100) {
					collector.setResult(100);;
				}
			}

			@Override public void onUploadSuccess(String arg0, String arg1) {
				if (collector.getFileInfos().get(0).getTrasactionId().equals(arg0) && (int)collector.getResult() == 100) {
					collector.setResult(ErrorCode.SUCCESS);
					collector.countDown();
				}
			}
    	};
    }
    
    private static void makeFileCallbackAndCancel(final MstpClient mstpClient, final FileCancelCollector collector, final boolean flag) {
    	pfc = new ProxyFileCallback() {
			@Override public void onDownloadFail(String arg0, int arg1) {
				if (!flag && collector.containTrasactionId(arg0) && collector.getFlagByTrasactionId(arg0)) {
					collector.removeTrasactionFromSet(arg0);
					if (collector.getSizeOfSet() <= 0) {
						collector.setResult(ErrorCode.SUCCESS);
						collector.countDown();
					}
				}
			}
			@Override public void onDownloadProgress(String arg0, int arg1) {
				if (!flag && collector.containTrasactionId(arg0) && arg1 >= collector.getCancelPoint()) {
					int tmp = mstpClient.cancelDownloadFile(arg0);
					if (tmp == ErrorCode.SUCCESS) {
						collector.putTrasactionId(arg0, true);
					} else {
						collector.setResult(tmp);
						collector.countDown();
					}
				}
			}
			@Override public void onDownloadSuccess(String arg0) {
				if (!flag && collector.containTrasactionId(arg0)) {
					collector.setResult(ErrorCode.ERR_UNEXPECT_RESULT);
					collector.countDown();
				}
			}
			@Override public void onUploadFail(String arg0, int arg1) {
				if (flag && collector.containTrasactionId(arg0) && collector.getFlagByTrasactionId(arg0)) {
					collector.removeTrasactionFromSet(arg0);
					if (collector.getSizeOfSet() <= 0) {
						collector.setResult(ErrorCode.SUCCESS);
						collector.countDown();
					}
				}
			}
			@Override public void onUploadProgress(String arg0, int arg1) {
				if (flag && collector.containTrasactionId(arg0) && arg1 >= collector.getCancelPoint()) {
					int tmp = mstpClient.cancelUploadFile(arg0);
					if (tmp == ErrorCode.SUCCESS) {
						collector.putTrasactionId(arg0, true);
					} else {
						collector.setResult(tmp);
						collector.countDown();
					}
				}
			}
			@Override public void onUploadSuccess(String arg0, String arg1) {
				if (flag && collector.containTrasactionId(arg0)) {
					collector.setResult(ErrorCode.ERR_UNEXPECT_RESULT);
					collector.countDown();
				}
			}
    	};
    }
    
    public static void makeFileUploadCallback(final FileloadCollector collector) {
    	if (detectFileLoad(collector, true)) {
    		return;
    	}
    	pfc = new ProxyFileCallback() {
			@Override public void onDownloadFail(String arg0, int arg1) { }
			@Override public void onDownloadProgress(String arg0, int arg1) { }
			@Override public void onDownloadSuccess(String arg0) { }
			@Override public void onUploadProgress(String arg0, int arg1) { }

			@Override public void onUploadFail(String arg0, int arg1) {
				detectFileLoad(collector, true);
			}
			@Override public void onUploadSuccess(String arg0, String arg1) {
				detectFileLoad(collector, true);
			}
    	};
    }
    
    private static boolean detectFileLoad(final FileloadCollector collector, boolean upload) {
    	int count = 0;
		for (FileloadInfo ele : collector.getFileInfos()) {
			if (fileMap.containsKey(ele.getTrasactionId()) && fileMap.get(ele.getTrasactionId()).getUploadFlag() == upload) {
				if (!fileMap.get(ele.getTrasactionId()).getFlag()) {
					collector.setResult(fileMap.get(ele.getTrasactionId()).getReason());
					collector.countDown();
					return true;			//快速结束
				} else {
					count++;
				}
			}
		}
		
		if (count == collector.getFileInfos().size()) {
			if (upload) {		//当前为上传时，需要遍历收集所有的 fileId 信息
				for (int i = 0; i < collector.getFileInfos().size(); i++) {
					collector.getFileInfos().get(i).setFileId(fileMap.get(collector.getFileInfos().get(i).getTrasactionId()).getFileId());
				}
			}
			collector.setResult(ErrorCode.SUCCESS);
			collector.countDown();
			return true;
		}
    	return false;
    }
    
    public static void makeFileDownloadCallback(final FileloadCollector collector) {
    	if (detectFileLoad(collector, false)) {
    		return;
    	}
    	pfc = new ProxyFileCallback() {
			@Override public void onDownloadFail(String arg0, int arg1) {
				detectFileLoad(collector, false);
			}
			@Override public void onDownloadSuccess(String arg0) {
				detectFileLoad(collector, false);
			}
			
			@Override public void onDownloadProgress(String arg0, int arg1) { }
			@Override public void onUploadFail(String arg0, int arg1) { }
			@Override public void onUploadProgress(String arg0, int arg1) { }
			@Override public void onUploadSuccess(String arg0, String arg1) { }
    	};
    }
    
    public static void clearFileCallback() {
    	pfc = null;
    }
    
    public static void makeMessageSendCallback(final MsgSendCollector collector) {
    	if (detectSendCallback(collector)) {		//内存数据对比
    		return;
    	}
    	
    	pmsc = new ProxyMessageSendCallback() {
			@Override public void onFail(String arg0, int arg1) {
				detectSendCallback(collector);
			}
			@Override public void onSuccess(String arg0, Message arg1) {
				detectSendCallback(collector);
			}

			@Override public void onProgress(String arg0, int arg1) { }
    	};
    }
    
    public static void clearMessageSendCallback() {
    	pmsc = null;
    }
    
    public static void makeMessageReceiveListener(final MsgListenerCollector collector) {
    	if (detectMessageReceive(collector)) {
    		return;
    	}
    	pml = new ProxyMessageListener() {
			@Override public boolean onMessageRecv(List<Message> arg0) {
				detectMessageReceive(collector);
				return true;
			}

			@Override public void onMessageStatus(String arg0, MessageStatus arg1, String arg2, List<String> arg3, String arg4) {}
    	};
    }
    
    public static void makeRevokeListener(final MsgListenerCollector collector) {
    	if(detectHaveReadOrRevoke(collector, MessageStatus.REVOKE) == ErrorCode.SUCCESS) {
    		return;
    	}
    	pml2 = new ProxyMessageListener() {
			@Override public boolean onMessageRecv(List<Message> arg0) {
				return true;
			}

			@Override public void onMessageStatus(String arg0, MessageStatus arg1, String arg2, List<String> arg3, String arg4) {
				detectHaveReadOrRevoke(collector, MessageStatus.REVOKE);
			}
    	};
    }
    
    public static void clearRevokeListener() {
    	pml2 = null;
    }
    
//    private static int detectRevoke(MsgListenerCollector collector) {
//    	if (msgCodeMap.keySet().containsAll(collector.getMapKey())) {
//    		int count = 0;
//    		for (Message ele : collector.getMapKey()) {
//    			if (msgCodeMap.get(ele.getMsgId()).getMessageStatus() != MessageStatus.REVOKE) {
//    				collector.setResult(ErrorCode.ERR_UNEXPECT_RESULT);
//    	    		collector.countDown();
//    	    		return ErrorCode.SUCCESS;
//    			} else {
//    				count++;
//    			}
//    		}
//    		if (count == collector.getMapKey().size()) {
//    			collector.setResult(ErrorCode.SUCCESS);
//	    		collector.countDown();
//	    		return ErrorCode.SUCCESS;
//    		} else {
//    			return ErrorCode.ERR_UNEXPECT_RESULT;
//    		}
//    	} else {
//    		return ErrorCode.ERR_UNEXPECT_RESULT;
//    	}
//    }
    
    private static int detectHaveReadOrRevoke(MsgListenerCollector collector, MessageStatus status) {
    	if (collector.getMapKey().size() <= 0) {
    		return ErrorCode.ERR_PARAM_ERROR;
    	}
    	
    	int count = 0;
    	for (Message key : collector.getMapKey()) {
    		if (msgCodeMap.get(key.getMsgId()) == null) {
    			return ErrorCode.ERR_UNEXPECT_RESULT;
    		} else if (msgCodeMap.get(key.getMsgId()).getMessageStatus() != status) {
    			collector.setResult(ErrorCode.ERR_UNEXPECT_RESULT);
    	   		collector.countDown();
    			return ErrorCode.ERR_UNEXPECT_RESULT;
    		} else {
    			count++;
    		}
    	}
		if (count == collector.getMapKey().size()) {
			collector.setResult(ErrorCode.SUCCESS);
	    	collector.countDown();
	    	return ErrorCode.SUCCESS;
		}
    	return ErrorCode.ERR_UNEXPECT_RESULT;
    }
    
    public static void clearMessageListener() {
    	pml = null;
    }
    
    public static void makeHaveReadListener(final MsgListenerCollector collector) {
    	if(detectHaveReadOrRevoke(collector, MessageStatus.READ) == ErrorCode.SUCCESS) {
    		return;
    	}
    	pml1 = new ProxyMessageListener() {
			@Override public boolean onMessageRecv(List<Message> arg0) {
				return true;
			}

			@Override public void onMessageStatus(String arg0, MessageStatus arg1, String arg2, List<String> arg3, String arg4) {
				detectHaveReadOrRevoke(collector, MessageStatus.READ);
			}
    	};
    }
    
    public static void clearHaveReadListener() {
    	pml1 = null;
    }
    

    
    public static boolean compareMap(Map<String, String> a, Map<String, String> b){
        for(Map.Entry<String, String> entry1 : a.entrySet()){
            String v1 = entry1.getValue();
            String v2 = b.get(entry1.getKey());
            if ((v1 == null && v2 != null) || (v1 != null && v2 == null)) {
            	return false;
            } else if (v1 == null && v2 == null) {
            	
            } else if (!v1.equals(v2)) {
            	return false;
            }
        }
        return true;
   }
    
    private static boolean compareMessage(Message a, Message b) {
    	if (a.getChatType() == b.getChatType() && a.getExpTime() == b.getExpTime() && a.getPriority() == b.getPriority() && a.getPushType() == b.getPushType()) {
    	} else {
    		return false;
    	}
    	
    	if (!compareMap(a.getExtAttrs(), b.getExtAttrs())) {
    		return false;
    	}
    	
    	if (a.getBodies().size() != b.getBodies().size()) {
    		return false;
    	}
    	for (int i = 0; i < a.getBodies().size(); i++) {
    		if (a.getBodies().get(i).getMsgType() == MessageType.TXT) {
    			if (!((TextMessageBody) (a.getBodies().get(i))).getContent().equals(((TextMessageBody) (b.getBodies().get(i))).getContent())) {
    				return false;
    			}
    		} else if (a.getBodies().get(i).getMsgType() == MessageType.FILE) {
    			if (!((FileMessageBody) (a.getBodies().get(i))).getFileId().equals(((FileMessageBody) (b.getBodies().get(i))).getFileId())) {
    				return false;
    			}
    		} else if (a.getBodies().get(i).getMsgType() == MessageType.AUDIO) {
    			if (!((AudioMessageBody) (a.getBodies().get(i))).getFileId().equals(((AudioMessageBody) (b.getBodies().get(i))).getFileId())) {
    				return false;
    			}
    		} else if (a.getBodies().get(i).getMsgType() == MessageType.IMAGE) {
    			if (!((ImageMessageBody) (a.getBodies().get(i))).getFileId().equals(((ImageMessageBody) (b.getBodies().get(i))).getFileId())) {
    				return false;
    			}
    		} else if (a.getBodies().get(i).getMsgType() == MessageType.VIDEO) {
    			if (!((VideoMessageBody) (a.getBodies().get(i))).getFileId().equals(((VideoMessageBody) (b.getBodies().get(i))).getFileId())) {
    				return false;
    			}
    		}
    	}
    	return true;
    }
    
    private static boolean detectMessageReceive(MsgListenerCollector collector) {
    	Log.e("XXX", "detectMessageReceive size " + msgMap.keySet().size());
    	int count = 0;
    	for (Message ele : collector.getMapKey()) {
    		CoreInfo tag = msgMap.get(ele.getMsgId());
    		if (tag != null && compareMessage((Message)tag.getObject(), ele)) {
    			count++;
    		}
    	}
    	
    	if (count == collector.getMapKey().size()) {		//校验是否全部收到
    		collector.setResult(ErrorCode.SUCCESS);
	        collector.countDown();
	        return true;
    	}
    	return false;
    }
    
    private static boolean detectSendCallback(MsgSendCollector collector) {
    	int count = 0;
    	for (int i = 0; i < collector.getMessageIDs().size(); i++) {		//遍历比较内存中的发送情况
    		Message ele = collector.getMessageIDs().get(i);
    		if (scinfoMap.containsKey(ele.getMsgId()) && scinfoMap.get(ele.getMsgId()).getFlag()) {
    			collector.getMessageIDs().set(i, (Message) scinfoMap.get(ele.getMsgId()).getObject());
    			count++;
    		} else if (scinfoMap.containsKey(ele.getMsgId()) && !scinfoMap.get(ele.getMsgId()).getFlag()) {
    			collector.setResult((int) scinfoMap.get(ele.getMsgId()).getObject());		//存在一个发送失败的情况，直接返回监听结果
        		collector.countDown();
    			return true;
    		}
    	}
    	
    	if (count == collector.getMessageIDs().size()) {		//所有都发送成功，认为监听成功
    		collector.setResult(0);
    		scinfoMap.clear();
    		collector.countDown();
    		return true;
    	} else {
    		return false;
    	}
    }
    
    public static void makeCloudDiskCallback(final FileloadCollector collector, final boolean uploadFlag) {
    	pcdc = new ProxyCloudDiskCallback() {
			@Override public void onDownloadProgress(String arg0, int arg1) { }
			@Override public void onUploadProgress(String arg0, int arg1) { }
			
			@Override public void onDownloadFail(String arg0, int arg1) {
				detectFileLoad(collector, uploadFlag);
			}

			@Override public void onDownloadSuccess(String arg0) {
				detectFileLoad(collector, uploadFlag);
			}

			@Override public void onUploadFail(String arg0, int arg1) {
				detectFileLoad(collector, uploadFlag);
			}

			@Override public void onUploadSuccess(String arg0, String arg1) {
				detectFileLoad(collector, uploadFlag);
			}
		};
    }
	
	public static void makeCancelCloudDiskCallback(final MstpClient mstpClient, final FileCancelCollector collector, final boolean flag) {
		pcdc = new ProxyCloudDiskCallback() {
			@Override public void onDownloadProgress(String arg0, int arg1) { 
				if (!flag && collector.containTrasactionId(arg0) && arg1 >= collector.getCancelPoint()) {
					Log.e("XXX", "onDownloadProgress canceled arg0=" + arg0 + ", arg1=" + arg1);
					int tmp = mstpClient.cancelDownloadFile(arg0);
					if (tmp == ErrorCode.SUCCESS) {
						collector.putTrasactionId(arg0, true);
					} else {
						collector.setResult(tmp);
						collector.countDown();
					}
				}
			}
			@Override public void onUploadProgress(String arg0, int arg1) { 
				Log.e("XXX", "onUploadProgress arg0=" + arg0 + "arg1=" + arg1);
				if (flag && collector.containTrasactionId(arg0) && arg1 >= collector.getCancelPoint()) {
					int tmp = mstpClient.cancelUploadFile(arg0);
					if (tmp == ErrorCode.SUCCESS) {
						collector.putTrasactionId(arg0, true);
					} else {
						collector.setResult(tmp);
						collector.countDown();
					}
				}
			}
			
			@Override public void onDownloadFail(String arg0, int arg1) {
				Log.e("XXX", "onDownloadFail arg0=" + arg0 + ", arg1=" + arg1);
				if (!flag && collector.containTrasactionId(arg0) && collector.getFlagByTrasactionId(arg0)) {
					Log.e("XXX", "onDownloadFail canceled arg0=" + arg0 + ", arg1=" + arg1);
					collector.removeTrasactionFromSet(arg0);
					if (collector.getSizeOfSet() <= 0) {
						collector.setResult(ErrorCode.SUCCESS);
						collector.countDown();
					}
				}
			}

			@Override public void onDownloadSuccess(String arg0) {
				Log.e("XXX", "onDownloadSuccess arg0=" + arg0);
				if (!flag && collector.containTrasactionId(arg0)) {
					collector.setResult(ErrorCode.ERR_UNEXPECT_RESULT);
					collector.countDown();
				}
			}

			@Override public void onUploadFail(String arg0, int arg1) {
				Log.e("XXX", "onUploadFail arg0=" + arg0 + "arg1=" + arg1);
				if (flag && collector.containTrasactionId(arg0) && collector.getFlagByTrasactionId(arg0)) {
					collector.removeTrasactionFromSet(arg0);
					if (collector.getSizeOfSet() <= 0) {
						collector.setResult(ErrorCode.SUCCESS);
						collector.countDown();
					}
				}
			}

			@Override public void onUploadSuccess(String arg0, String arg1) {
				Log.e("XXX", "onUploadSuccess arg0=" + arg0 + "arg1=" + arg1);
				if (flag && collector.containTrasactionId(arg0)) {
					collector.setResult(ErrorCode.ERR_UNEXPECT_RESULT);
					collector.countDown();
				}
			}
		};
	}
	
	public static void clearCloudDiskCallback() {
		pcdc = null;
	}
}

